package com.atguigu.c_designed.m2stucturalModel.s2Bridge;

/**
 *  桥接模式即将抽象部分与它的实现部分分离开来，使他们都可以独立变化。
 * 桥接模式将继承关系转化成关联关系，它降低了类与类之间的耦合度，减少了系统中类的数量，也减少了代码量。
 * 实现系统可能有多个角度分类，每一种角度都可能变化，那么把这种多角度分类给分离出来让他们独立变化，减少他们之间耦合。
 * 桥接模式中的所谓脱耦，就是指在一个软件系统的抽象化和实现化之间使用关联关系（组合或者聚合关系）而不是继承关系，从而使两者可以相对独立地变化，这就是桥接模式的用意。
 */
public class Client {
    public static void main(String[] args) {
        OperationSystem operationSystem = new Mac(new AviFileDecoder());
        operationSystem.play("叶问");
    }
}

/**
 *  模式优缺点
 * 优点
 * 1、分离抽象接口及其实现部分。提高了比继承更好的解决方案。
 * 2、桥接模式提高了系统的可扩充性，在两个变化维度中任意扩展一个维度，都不需要修改原有系统。
 * 3、实现细节对客户透明，可以对用户隐藏实现细节。
 * 缺点
 * 1、桥接模式的引入会增加系统的理解与设计难度，由于聚合关联关系建立在抽象层，要求开发者针对抽象进行设计与编程。
 * 2、桥接模式要求正确识别出系统中两个独立变化的维度，因此其使用范围具有一定的局限性。
 */

/**
 * 使用场景
 * - 当一个类存在两个独立变化的维度，且这两个维度都需要进行扩展时。
 * - 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
 * - 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。避免在两个层次之间建立静态的继承联系，通过桥接模式可以使它们在抽象层建立一个关联关系。
 */
abstract class OperationSystem {
    FileDecoder fileDecoder;
    abstract void play(String fileName);
}

class Windows extends OperationSystem {

    public Windows(FileDecoder fileDecoder) {
        this.fileDecoder = fileDecoder;
    }

    @Override
    void play(String fileName) {
        System.out.println("windows播放。。。。");
        fileDecoder.decode(fileName);
    }
}

class Mac extends OperationSystem {
    public Mac(FileDecoder fileDecoder) {
        this.fileDecoder = fileDecoder;
    }

    @Override
    void play(String fileName) {
        System.out.println("Mac播放。。。。");
        fileDecoder.decode(fileName);
    }
}

interface FileDecoder{
    void decode(String filename);
}

class AviFileDecoder implements FileDecoder{
    @Override
    public void decode(String filename) {
        System.out.println("AviFileDecoder fileDecode...."+filename);
    }
}

class Mp4FileDecoder implements FileDecoder{
    @Override
    public void decode(String filename) {
        System.out.println("Mp4FileDecoder fileDecode...."+filename);
    }
}